#include <windows.h>

#include <GL/GL.h>
#include <GL/Glaux.h>
#include <GL/Glu.h>

#include "math.h"
//
///////////////////////////////////////////////////////////////////
//definitions
#define PI 3.1415926535898
GLUquadricObj *pacman;


#define ImageWidth 256
#define WindowWidth 512

//circular window components
GLfloat Image[WindowWidth][WindowWidth][4];
float ratioWidth,ratioHeight;

//line patterns components
//GLfloat Stripes[4][ImageWidth][ImageWidth][4];

//extern
GLuint texture[6];
//
//____________________________________________________________
void Generate_Rectangle(int ListNumber, float red, float green, float blue, int Width, int Height){
	glNewList(ListNumber,GL_COMPILE);
		glColor3f(red,green,blue);
		glRecti(0,0,Width,Height);	// rectangle
	glEndList();
}
//
void Generate_Line(int ListNumber, float Thickness, float red, float green, float blue, int Height, int Width){
	glNewList(ListNumber,GL_COMPILE);
		glLineWidth(Thickness);
		glColor3f(red,green,blue);
		glBegin(GL_LINES);
        glVertex2i(-Width/2,-Height/2);
		    glVertex2i(Width/2,Height/2);
		glEnd();
	glEndList();
}
//
void Generate_PointLine(int ListNumber, float Thickness, float red, float green, float blue, int Xa, int Ya, int Xb, int Yb){
	glNewList(ListNumber,GL_COMPILE);
		glLineWidth(Thickness);
		glColor3f(red,green,blue);
		glBegin(GL_LINES);
        glVertex2i(Xa,Ya);
		    glVertex2i(Xb,Yb);
		glEnd();
	glEndList();
}
//
void Generate_3PointLine(int ListNumber, float Thickness, float red, float green, float blue, int Xa, int Ya, int Xb, int Yb, int Xc, int Yc, int Xd, int Yd, int Xe, int Ye, int Xf, int Yf){
	glNewList(ListNumber,GL_COMPILE);
		glLineWidth(Thickness);
		glColor3f(red,green,blue);
		glBegin(GL_LINES);
        glVertex2i(Xa,Ya);
		    glVertex2i(Xb,Yb);
        glVertex2i(Xc,Yc);
		    glVertex2i(Xd,Yd);
        glVertex2i(Xe,Ye);
		    glVertex2i(Xf,Yf);
	glEnd();
	glEndList();
}
//
void Generate_Quad(int ListNumber, float red, float green, float blue, int PointAx,int PointAy, int PointBx,int PointBy, int PointCx,int PointCy, int PointDx,int PointDy){
	glNewList(ListNumber,GL_COMPILE);
		glColor3f(red,green,blue);
		glBegin(GL_QUADS);
		glVertex2i(PointAx,PointAy);
		glVertex2i(PointBx,PointBy);
		glVertex2i(PointCx,PointCy);
		glVertex2i(PointDx,PointDy);
		glEnd();
	glEndList();
}
void Generate_Pacman(int ListNumber, float red, float green, float blue, float innerRadius, float outerRadius, int slices, int loops, float startAngle, float sweepAngle){
  glNewList(ListNumber,GL_COMPILE);
    glColor3f(red,green,blue);
    gluPartialDisk(pacman, innerRadius, outerRadius, slices, loops, startAngle, sweepAngle);
  glEndList();
}
/*
void Generate_RectangleSurround(int ListNumber, float red, float green, float blue, int Width, int Height, int posX, int posY, int progWidth, int progHeight){
	glNewList(ListNumber,GL_COMPILE);
		glColor3f(red,green,blue);
		glRecti(0,0,progWidth,progHeight/2+posY-Height/2);
		glRecti(0,progHeight/2+posY-Height/2,progWidth/2+posX-Width/2,progHeight);
		glRecti(progWidth/2+posX-Width/2,progHeight/2+posY+Height/2,progWidth,progHeight);
		glRecti(progWidth/2+posX+Width/2,progHeight/2+posY+Height/2,progWidth,progHeight/2+posY-Height/2);
	glEndList();
} */
//
void Generate_CircleSurround(int ListNumber, float red, float green, float blue, int Border, int Radius, int posX, int posY, int progWidth, int progHeight){
	float opacity=1.0,radius=0.0;
	int x,y;
	
	ratioWidth=((float)WindowWidth/progWidth);
	ratioHeight=((float)WindowWidth/progHeight);
	int winRadius=(int)(((float)WindowWidth/progWidth)*Radius);
	int winBorder=(int)(((float)WindowWidth/progWidth)*Border);

  for(x=0;x<WindowWidth;x++){
		for(y=0;y<WindowWidth;y++){
			radius = (float) sqrt(pow((x-WindowWidth/2),2)+pow((y-WindowWidth/2),2));
			opacity=1.0;
      blue=0.67;
			if(x<-1*cos(190)*winRadius&&x>-1*cos(230)*winRadius&&y>-1*sin(190)*winRadius&&y<-1*sin(230)*winRadius){
//		    opacity=(float)(1.0-1/20*(asin(y)/Radius));
        opacity=1.0;
        blue=0.9;
        }
//			if(radius<(float)(winRadius/2)&&winBorder==0)
//				opacity=0.0;
			Image[x][y][0]= red;
			Image[x][y][1]= green;
			Image[x][y][2]= blue;
			Image[x][y][3]= opacity;
		}
	}
            /*
	for(x=0;x<WindowWidth;x++){
		for(y=0;y<WindowWidth;y++){
			radius = (float) sqrt(pow((x-WindowWidth/2),2)+pow((y-WindowWidth/2),2));
			opacity=1.0;
			if(radius<(float)(winRadius/2)&&winBorder!=0)
				opacity=(float)(1.0-((winRadius/2)-radius)/winBorder);
			if(radius<(float)(winRadius/2)&&winBorder==0)
				opacity=0.0;
			Image[x][y][0]= red;
			Image[x][y][1]= green;
			Image[x][y][2]= blue;
			Image[x][y][3]= opacity;
		}
	}         */
  
		glBindTexture(GL_TEXTURE_2D,texture[5]);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
		glTexImage2D(GL_TEXTURE_2D, 0, 4, WindowWidth, WindowWidth, 0, GL_RGBA, GL_FLOAT, &Image[0][0][0]);

	glNewList(ListNumber,GL_COMPILE);
		glBindTexture(GL_TEXTURE_2D,texture[5]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 0.0); 
			glVertex3i(0, 0, 0);
			glTexCoord2f(0.0, 1.0); 
			glVertex3i(0, progHeight, 0);
			glTexCoord2f(1.0, 1.0); 
			glVertex3i(progWidth, progHeight, 0);
			glTexCoord2f(1.0, 0.0); 
			glVertex3i(progWidth, 0, 0);
		glEnd();
	glEndList();
}
//
/*
void Generate_LinePattern(float red, float green, float blue, int Distance, int m, int LineThickness, int number){
	int x,y,i=0;
	int thick;

	if(m!=11){
		for(x=0;x<ImageWidth;x++){
			for(y=0;y<ImageWidth;y++){
				Stripes[number][x][y][3]= 0.0f;
				Stripes[number][x][y][0]= red;
				Stripes[number][x][y][1]= green;
				Stripes[number][x][y][2]= blue;
			}
		}

		for(x=0;x<ImageWidth;x++){
			for(y=0;y<ImageWidth;y++){
				for(i=ImageWidth/2;i>-ImageWidth/2;i--){
					for(thick=0;thick<LineThickness;thick++){
						if(y==m*x+Distance*i+thick){
							Stripes[number][x][y][3]= 1.0f;
							Stripes[number][x][y][0]= red;
							Stripes[number][x][y][1]= green;
							Stripes[number][x][y][2]= blue;
						}
					}
				}
			}
			i=0;
		}
		for(x=0;x<ImageWidth;x++){
			for(y=0;y<ImageWidth;y++){
				if(Stripes[number][x][y][0]!= red){
						Stripes[number][x][y][3]= 0.0f;
						Stripes[number][x][y][0]= red;
						Stripes[number][x][y][1]= green;
						Stripes[number][x][y][2]= blue;
				}
			}
		}
	}

	if(m==11){
		m=0;
		for(x=0;x<ImageWidth;x++){
			for(y=0;y<ImageWidth;y++){
				Stripes[number][y][x][3]= 0.0f;
				Stripes[number][y][x][0]= red;
				Stripes[number][y][x][1]= green;
				Stripes[number][y][x][2]= blue;
			}
		}

		for(x=0;x<ImageWidth;x++){
			for(y=0;y<ImageWidth;y++){
				for(i=ImageWidth/2;i>-ImageWidth/2;i--){
					for(thick=0;thick<LineThickness;thick++){
						if(y==m*x+Distance*i+thick){
							Stripes[number][y][x][3]= 1.0f;
							Stripes[number][y][x][0]= red;
							Stripes[number][y][x][1]= green;
							Stripes[number][y][x][2]= blue;
						}
					}
				}
			}
			i=0;
		}
		for(x=0;x<ImageWidth;x++){
			for(y=0;y<ImageWidth;y++){
				if(Stripes[number][y][x][0]!= red){
						Stripes[number][y][x][3]= 0.0f;
						Stripes[number][y][x][0]= red;
						Stripes[number][y][x][1]= green;
						Stripes[number][y][x][2]= blue;
				}
			}
		}
	}
		glBindTexture(GL_TEXTURE_2D, texture[number]);	
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
		glTexImage2D(GL_TEXTURE_2D, 0, 4, ImageWidth, ImageWidth, 0, GL_RGBA, GL_FLOAT, &Stripes[number][0][0][0]);

}
//
void Generate_StripedQUADS(int ListNumber, int Width, int Height, int Slant, int Gap, int numberLeft, int numberRight, int Distance, int LineThickness, int m){
	float dist=(float)((Distance+LineThickness)/2);
	float slant = (float)(tan(PI*Slant/180)*Height);
	float Ausgleich=(float)((Distance+LineThickness)/(2.0*(tan(PI*Slant/180)*Height)));
	
	if(Slant==0)Ausgleich=0;
	if((m==1||m==-1)&&Slant!=0) dist=(float)(dist/(sin(PI*Slant/180)*Height));
	if((m==1||m==-1)&&Slant==0) dist=dist/2;
	if(m==0){

		dist=0;
		Ausgleich=0;
		slant=0;
	}

	glNewList(ListNumber,GL_COMPILE);
		glBindTexture(GL_TEXTURE_2D,texture[numberLeft]);
		glBegin(GL_QUADS);
			if(Slant>0){
				glTexCoord2f(0.0, 0.0); 
				glVertex2f(slant/2+Ausgleich, dist);
				glTexCoord2f(0.0, 1.0); 
				glVertex2f(slant/2+Ausgleich, (float)(Height+dist));
				glTexCoord2f(1.0, 1.0); 
				glVertex2f(Width+slant/2-Gap/2+Ausgleich, (float)(Height+dist));
				glTexCoord2f((float)(1.0-slant/Width), 0.0); 
				glVertex2f(Width-slant/2-Gap/2+Ausgleich, dist);
			}
			if(Slant<=0){
				glTexCoord2f(0.0, 0.0); 
				glVertex2f(-slant/2, 0.0);
				glTexCoord2f(0.0, 1.0); 
				glVertex2f(-slant/2, (float)(Height));
				glTexCoord2f((float)(1.0+slant/Width), 1.0); 
				glVertex2f(Width+slant/2-Gap/2, (float)(Height));
				glTexCoord2f(1.0, 0.0); 

				glVertex2f(Width-slant/2-Gap/2, 0.0);
			}
		glEnd();
			
		glBindTexture(GL_TEXTURE_2D,texture[numberRight]);
		glBegin(GL_QUADS);
			if(Slant>0){
				glTexCoord2f(0.0, 0.0); 
				glVertex2f(Width-slant/2+Gap/2, 0.0);
				glTexCoord2f(slant/Width, 1.0); 
				glVertex2f(Width+slant/2+Gap/2, (float)Height);
				glTexCoord2f(1.0, 1.0); 
				glVertex2f(2*Width-slant/2, (float)Height);
				glTexCoord2f(1.0, 0.0); 
				glVertex2f(2*Width-slant/2, 0.0);
			}
			if(Slant<=0){
				glTexCoord2f(-slant/Width, 0.0); 
				glVertex2f(Width-slant/2+Gap/2-Ausgleich, dist);
				glTexCoord2f(0.0, 1.0); 
				glVertex2f(Width+slant/2+Gap/2-Ausgleich, (float)(Height+dist));
				glTexCoord2f(1.0, 1.0); 
				glVertex2f(2*Width+slant/2-Ausgleich, (float)(Height+dist));
				glTexCoord2f(1.0, 0.0); 
				glVertex2f(2*Width+slant/2-Ausgleich, dist);
			}
		glEnd();
	glEndList();
}

void Generate_CircularLine(int ListNumber, float red, float green, float blue, int MinLineX, int MaxLineX, int MinLineY, int MaxLineY, int Radius, int posX, int posY, int progWidth, int progHeight){
	float opacity=1.0,radius=0.0;
	int x,y;

	ratioWidth=((float)WindowWidth/progWidth);
	ratioHeight=((float)WindowWidth/progHeight);

	for(x=0;x<WindowWidth;x++){
		for(y=0;y<WindowWidth;y++){
			opacity=0.0;
			Image[x][y][0]= red;

			Image[x][y][1]= green;
			Image[x][y][2]= blue;
			Image[x][y][3]= opacity;
		}
	}
	for(x=MinLineX*ratioWidth;x<MaxLineX*ratioWidth;x++){
		for(y=MinLineY*ratioHeight;y<MaxLineY*ratioHeight;y++){
			radius = (float) sqrt(pow((x-WindowWidth/2),2)+pow((y-WindowWidth/2),2));
			opacity=0.0;
			if(radius<Radius)
				opacity=1.0;
			if(radius>Radius)
				opacity=0.0;
			Image[x][y][0]= red;
			Image[x][y][1]= green;
			Image[x][y][2]= blue;
			Image[x][y][3]= opacity;
		}
	}
		glBindTexture(GL_TEXTURE_2D,texture[5]);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
		glTexImage2D(GL_TEXTURE_2D, 0, 4, WindowWidth, WindowWidth, 0, GL_RGBA, GL_FLOAT, &Image[0][0][0]);

	glNewList(ListNumber,GL_COMPILE);
		glBindTexture(GL_TEXTURE_2D,texture[5]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 0.0);
			glVertex3i(0, 0, 0);
			glTexCoord2f(0.0, 1.0);
			glVertex3i(0, progHeight, 0);
			glTexCoord2f(1.0, 1.0);
			glVertex3i(progWidth, progHeight, 0);
			glTexCoord2f(1.0, 0.0);
			glVertex3i(progWidth, 0, 0);
		glEnd();
	glEndList();
}

void Generate_MultipleLines(int ListNumber, int NumberOfLines, int DistanceOfLines, int DistanceFromFixation, int LineLength, int Orientation){
 	glNewList(ListNumber,GL_COMPILE);
  
  if(Orientation<=45){
    for(int i=0;i<NumberOfLines;i++){
        glPushMatrix();
        glTranslatef(-DistanceFromFixation-DistanceOfLines*(NumberOfLines-1)+DistanceOfLines*i,0.,0.);
        glRotatef(Orientation,0.,0.,1.);
  		  glBegin(GL_LINES);
          glVertex2i(0,-LineLength/2);
		      glVertex2i(0,LineLength/2);
        glEnd();
        glRotatef(-Orientation,0.,0.,1.);
        glTranslatef(DistanceFromFixation+DistanceOfLines*(NumberOfLines-1)-DistanceOfLines*i,0.,0.);
        glPopMatrix();

    }
    for(int i=0;i<NumberOfLines;i++){
		  glPushMatrix();
      glTranslatef(DistanceFromFixation+DistanceOfLines*i,0.,0.);
      glRotatef(Orientation,0.,0.,1.);
      glBegin(GL_LINES);
        glVertex2i(0,-LineLength/2);
		    glVertex2i(0,LineLength/2);
		  glEnd();
      glRotatef(-Orientation,0.,0.,1.);
      glTranslatef(-DistanceFromFixation+DistanceOfLines*i,0.,0.);
      glPopMatrix();
    }
  }
  if(Orientation>45){
//
    for(int i=0;i<NumberOfLines;i++){
      glPushMatrix();
      glTranslatef(-DistanceFromFixation-LineLength,-DistanceOfLines*(NumberOfLines-1)/2+DistanceOfLines*i,0.);
      glRotatef(Orientation,0.,0.,1.);
      glBegin(GL_LINES);
        glVertex2i(-LineLength/2,0);
        glVertex2i(LineLength/2,0);
		  glEnd();
      glRotatef(-Orientation,0.,0.,1.);
      glTranslatef(DistanceFromFixation+LineLength,DistanceOfLines*(NumberOfLines-1)/2-DistanceOfLines*i,0.);
      glPopMatrix();
    }
    for(int i=0;i<NumberOfLines;i++){
      glPushMatrix();
      glTranslatef(DistanceFromFixation,-DistanceOfLines*(NumberOfLines-1)/2+DistanceOfLines*i,0.);
      glRotatef(Orientation,0.,0.,1.);
      glBegin(GL_LINES);
        glVertex2i(-LineLength/2,0);
		    glVertex2i(LineLength/2,0);
		  glEnd();
      glTranslatef(-DistanceFromFixation,-DistanceOfLines*(NumberOfLines-1)/2+DistanceOfLines*i,0.);
      glRotatef(-Orientation,0.,0.,1.);
      glPopMatrix();
    }
  }
glEndList();
} */